// mapmanager.cpp
#include "mapmanager.h"
#include <QFile>
#include <QTextStream>
#include <QString>  // 显式包含QString头文件，解决Qt::SkipEmptyParts问题
#include <QDebug>

MapManager::MapManager(QObject *parent) : QObject(parent) {}

char MapManager::getElementChar(MapElement element) {
    switch (element) {
        case MapElement::Floor: return ' ';
        case MapElement::Wall: return '#';
        case MapElement::Box: return '$';
        case MapElement::Target: return '.';
        case MapElement::Player: return '@';
        case MapElement::BoxOnTarget: return '*';
        case MapElement::PlayerOnTarget: return '+';
        default: return ' ';
    }
}

MapElement MapManager::getCharElement(char c) {
    switch (c) {
        case ' ': return MapElement::Floor;
        case '#': return MapElement::Wall;
        case '$': return MapElement::Box;
        case '.': return MapElement::Target;
        case '@': return MapElement::Player;
        case '*': return MapElement::BoxOnTarget;
        case '+': return MapElement::PlayerOnTarget;
        default: return MapElement::Floor;
    }
}

bool MapManager::loadMapFromFile(const QString &filePath, MapData &outMap) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "无法打开地图文件:" << filePath;
        return false;
    }

    QTextStream in(&file);
    QString content = in.readAll();
    file.close();

    return parseMapContent(content, outMap);
}

bool MapManager::parseMapContent(const QString &content, MapData &outMap) {
    outMap = MapData();
    QStringList lines = content.split('\n', QString::SkipEmptyParts);  // 按行分割，跳过空行
    if (lines.isEmpty()) {
        qDebug() << "解析失败：地图文件为空";
        return false;
    }

    // 地图行数 = 有效行数（非空行）
    outMap.rows = lines.size();
    // 地图列数 = 第一行的原始长度（保留空格，不trim）
    outMap.cols = lines[0].size();  // 关键：去掉trimmed()，保留所有字符（包括空格）
    qDebug() << "解析到地图大小：" << outMap.rows << "行 x" << outMap.cols << "列";

    // 初始化网格，默认全为空地（Empty）
    outMap.grid.resize(outMap.rows);
    for (int row = 0; row < outMap.rows; ++row) {
        outMap.grid[row].resize(outMap.cols, MapElement::Floor);  // 列数严格按第一行长度

        QString line = lines[row];  // 保留原始行（包括空格）
        // 确保每行长度与第一行一致（否则补空格或截断，避免越界）
        if (line.size() < outMap.cols) {
            line += QString(outMap.cols - line.size(), ' ');  // 短行补空格
        } else if (line.size() > outMap.cols) {
            line = line.left(outMap.cols);  // 长行截断
        }

        // 逐字符解析
        for (int col = 0; col < outMap.cols; ++col) {
            QChar c = line[col];
            switch (c.toLatin1()) {
                case '@':  // 玩家（空地）
                    outMap.grid[row][col] = MapElement::Player;
                    outMap.playerStartPos = QPoint(row, col);  // 记录初始位置
                    break;

                case '$':  // 箱子（空地）
                    outMap.grid[row][col] = MapElement::Box;
                    break;
            case '+':  // 玩家（目标点上）
                outMap.grid[row][col] = MapElement::PlayerOnTarget;
                outMap.playerStartPos = QPoint(row, col);
                outMap.targetPositions.push_back(QPoint(row, col));  // 正确：用 push_back
                break;

            case '*':  // 箱子（目标点上）
                outMap.grid[row][col] = MapElement::BoxOnTarget;
                outMap.targetPositions.push_back(QPoint(row, col));  // 正确
                break;

            case '.':  // 目标点（无玩家/箱子）
                outMap.grid[row][col] = MapElement::Target;
                outMap.targetPositions.push_back(QPoint(row, col));  // 正确
                break;
                case '#':  // 墙
                    outMap.grid[row][col] = MapElement::Wall;
                    break;
                case ' ':  // 空地（必须保留，不能删）
                    outMap.grid[row][col] = MapElement::Floor;
                    break;
                default:  // 未知字符，视为空地
                    outMap.grid[row][col] = MapElement::Floor;
                    qDebug() << "警告：未知字符" << c << "在位置" << row << "," << col;
                    break;
            }
        }
    }

    // 验证玩家是否存在（必须有且只有1个）
    int playerCount = 0;
    for (int row = 0; row < outMap.rows; ++row) {
        for (int col = 0; col < outMap.cols; ++col) {
            if (outMap.grid[row][col] == MapElement::Player ||
                outMap.grid[row][col] == MapElement::PlayerOnTarget) {
                playerCount++;
            }
        }
    }
    if (playerCount != 1) {
        qDebug() << "解析失败：玩家数量错误（应为1，实际" << playerCount << "）";
        return false;
    }

    qDebug() << "地图解析成功：玩家位置" << outMap.playerStartPos
             << "，目标点数量" << outMap.targetPositions.size();
    return true;
}

bool MapManager::validateMap(const MapData &map) {
    // 检查箱子和目标点数量是否匹配
    int boxCount = 0;
    for (int i = 0; i < map.rows; ++i) {
        for (int j = 0; j < map.cols; ++j) {
            auto elem = map.grid[i][j];
            if (elem == MapElement::Box || elem == MapElement::BoxOnTarget) {
                boxCount++;
            }
        }
    }
    return boxCount == map.targetPositions.size();
}

bool MapManager::saveMapToFile(const QString &filePath, const MapData &map) {
    if (!validateMap(map)) return false;

    QFile file(filePath);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) return false;

    QTextStream out(&file);
    for (int i = 0; i < map.rows; ++i) {
        for (int j = 0; j < map.cols; ++j) {
            out << getElementChar(map.grid[i][j]);
        }
        out << '\n';
    }

    file.close();
    return true;
}
